package org.linlinjava.litemall.mechanismadmin.web;

import com.github.pagehelper.PageInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.systemConfig.SystemConfig;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.mechanismadmin.annotation.LoginAdmin;
import org.linlinjava.litemall.mechanismadmin.dao.GoodsAllinone;
import org.linlinjava.litemall.mechanismadmin.util.CatVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/mechanismadmin/goodsManage")
public class MechanismGoodsManageController {
    private final Log logger = LogFactory.getLog(MechanismGoodsManageController.class);

    @Autowired
    private PlatformTransactionManager txManager;

    @Autowired
    private LitemallMechanismGoodsService mechanismGoodsService;

    @Autowired
    private LitemallMechanismProductService mechanismProductService;

    @Autowired
    private LitemallMechanismGoodsSpecificationService mechanismGoodsSpecificationService;

    @Autowired
    private LitemallMechanismGoodsAttributeService mechanismGoodsAttributeService;

    @Autowired
    private LitemallMechanismGoodsCategoryService mechanismGoodsCategoryService;

    @Autowired
    private LitemallMechanismGoodsCheckService mechanismGoodsCheckService;

    @GetMapping("/list")
    public Object list(
            @LoginAdmin Integer adminId,
            String goodsSn, String name, Integer mechanismId,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "limit", defaultValue = "10") Integer limit,
            String sort, String order){
        if(adminId == null){
            return ResponseUtil.unlogin();
        }

        List<LitemallMechanismGoods> goodsList = mechanismGoodsService.querySelective(goodsSn, name, mechanismId, page, limit, sort, order);
        long total = PageInfo.of(goodsList).getTotal();
        Map<String, Object> data = new HashMap<>();
        data.put("total", total);
        data.put("items", goodsList);
        return ResponseUtil.ok(data);
    }

    @GetMapping("productDetail")
    public Object productDetail(Integer goodId){
        List<LitemallMechanismProduct> product = mechanismProductService.queryByGid(goodId);
        Map<String, Object> data = new HashMap<>(16);
        data.put("product", product);
        return ResponseUtil.ok(data);
    }

    @GetMapping("/totalList")
    public Object totalList(@LoginAdmin Integer adminId,
                       String goodsSn, String name, Integer mechanismId,
                       String sort, String order){

        List<LitemallMechanismGoods> goodsList = mechanismGoodsService.queryTotalSelective(goodsSn, name, mechanismId, sort, order);

        Map<String, Object> data = new HashMap<>();
        data.put("items", goodsList);

        return ResponseUtil.ok(data);
    }

    /*
     * TODO
     * 目前商品修改的逻辑是
     * 1. 更新litemall_mechanism_goods表
     * 2. 逻辑删除litemall_mechanism_goods_specification、litemall_mechanism_goods_attribute、litemall_mechanism_product
     * 3. 添加litemall_mechanism_goods_specification、litemall_mechanism_goods_attribute、litemall_mechanism_product
     *
     * 这里商品三个表的数据采用删除再跟新的策略是因为
     * 商品编辑页面，管理员可以添加删除商品规格、添加删除商品属性，因此这里仅仅更新表是不可能的，
     * 因此这里只能删除所有旧的数据，然后添加新的数据
     */
    @PostMapping("/update")
    public Object update(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){
        if(adminId == null){
            return ResponseUtil.unlogin();
        }

        LitemallMechanismGoods mechanismGoods = goodsAllinone.getMechanismGoods();
        LitemallMechanismGoodsAttribute[] mechanismAttributes = goodsAllinone.getMechanismAttributes();
        LitemallMechanismGoodsSpecification[] mechanismSpecifications = goodsAllinone.getMechanismSpecifications();
        LitemallMechanismProduct[] mechanismProducts = goodsAllinone.getMechanismProducts();

        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            if(mechanismGoods.getDiscountsEndTime() != null && mechanismGoods.getDiscountsEndTime() != null) {
                DateTimeFormatter df1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                DateTimeFormatter df2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                String localTime = df1.format(mechanismGoods.getDiscountsEndTime()) + " 23:59:59";
                LocalDateTime ldt2 = LocalDateTime.parse(localTime,df2);
                mechanismGoods.setDiscountsEndTime(ldt2);
                mechanismGoods.setIsCheck(new Byte("0"));
            }
            // 商品基本信息表litemall_goods
            if(mechanismGoods.getIsOnSale()){
                mechanismGoodsService.updateById(mechanismGoods);
            }
            else if(!mechanismGoods.getIsOnSale()){
                mechanismGoods.setDiscountsAddTime(null);
                mechanismGoods.setDiscountsEndTime(null);
                mechanismGoodsService.updateById1(mechanismGoods);
            }

            Integer gid = mechanismGoods.getId();
            mechanismGoodsCheckService.updateDeletedByGoodsId(mechanismGoods.getId());
            mechanismGoodsSpecificationService.deleteByGid(gid);
            mechanismGoodsAttributeService.deleteByGid(gid);
            mechanismProductService.deleteByGid(gid);

            // 商品规格表litemall_goods_specification
            Map<String, Integer> specIds = new HashMap<>();
            for(LitemallMechanismGoodsSpecification specification : mechanismSpecifications){
                specification.setGoodsId(mechanismGoods.getId());
                specification.setAddTime(LocalDateTime.now());
                mechanismGoodsSpecificationService.add(specification);
                specIds.put(specification.getValue(), specification.getId());
            }

            // 商品参数表litemall_goods_attribute
            for(LitemallMechanismGoodsAttribute attribute : mechanismAttributes){
                attribute.setGoodsId(mechanismGoods.getId());
                attribute.setAddTime(LocalDateTime.now());
                mechanismGoodsAttributeService.add(attribute);
            }

            // 商品货品表litemall_product
            for(LitemallMechanismProduct product : mechanismProducts){
                product.setGoodsId(mechanismGoods.getId());
                product.setAddTime(LocalDateTime.now());
                mechanismProductService.add(product);
            }
        } catch (Exception ex) {
            txManager.rollback(status);
            logger.error("系统内部错误", ex);
        }
        txManager.commit(status);

        return ResponseUtil.ok();
    }

    @PostMapping("/delete")
    public Object delete(@LoginAdmin Integer adminId, @RequestBody LitemallMechanismGoods goods){
        if(adminId == null){
            return ResponseUtil.unlogin();
        }

        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            Integer gid = goods.getId();
            mechanismGoodsService.deleteById(gid);
            mechanismGoodsCheckService.updateDeletedByGoodsId(goods.getId());
            mechanismGoodsSpecificationService.deleteByGid(gid);
            mechanismGoodsAttributeService.deleteByGid(gid);
            mechanismProductService.deleteByGid(gid);
        } catch (Exception ex) {
            txManager.rollback(status);
            logger.error("系统内部错误", ex);
        }
        txManager.commit(status);
        return ResponseUtil.ok();
    }

    @PostMapping("/check")
    public Object check(@LoginAdmin Integer adminId, @RequestBody LitemallMechanismGoods goods){
        if(adminId == null){
            return ResponseUtil.unlogin();
        }

        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            LitemallMechanismGoodsCheck check = new LitemallMechanismGoodsCheck();
            check.setMechanismId(goods.getMechanismId());
            check.setAddTime(LocalDateTime.now());
            check.setGoodsId(goods.getId());
            check.setIsCheck(new Byte("1"));
            check.setGoodsName(goods.getName());
            check.setDeleted(false);
            mechanismGoodsCheckService.add(check);
            goods.setIsCheck(new Byte("1"));
            mechanismGoodsService.updateById(goods);
        } catch (Exception ex) {
            txManager.rollback(status);
            logger.error("系统内部错误", ex);
            return ResponseUtil.fail(403, "下单失败");
        }
        txManager.commit(status);
        return ResponseUtil.ok();
    }

    @PostMapping("/create")
    public Object create(@LoginAdmin Integer adminId, @RequestBody GoodsAllinone goodsAllinone){
        if(adminId == null){
            return ResponseUtil.unlogin();
        }

        LitemallMechanismGoods mechanismGoods = goodsAllinone.getMechanismGoods();
        LitemallMechanismGoodsAttribute[] mechanismAttributes = goodsAllinone.getMechanismAttributes();
        LitemallMechanismGoodsSpecification[] mechanismSpecifications = goodsAllinone.getMechanismSpecifications();
        LitemallMechanismProduct[] mechanismProducts = goodsAllinone.getMechanismProducts();
        String name = mechanismGoods.getName();
        if(mechanismGoodsService.checkExistByName(name,mechanismGoods.getMechanismId())){
            return ResponseUtil.fail(403, "商品名已经存在");
        }

        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        try {
            // 商品基本信息表litemall_goods
            if(!mechanismGoods.getIsOnSale()){
                mechanismGoods.setDiscountsAddTime(null);
                mechanismGoods.setDiscountsEndTime(null);
            }
            if(mechanismGoods.getDiscountsEndTime() != null && mechanismGoods.getDiscountsEndTime() != null) {
                DateTimeFormatter df1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                DateTimeFormatter df2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                String localTime = df1.format(mechanismGoods.getDiscountsEndTime()) + " 23:59:59";
                LocalDateTime ldt2 = LocalDateTime.parse(localTime,df2);
                mechanismGoods.setDiscountsEndTime(ldt2);
            }

            mechanismGoods.setIsCheck(new Byte("0"));
            mechanismGoods.setAddTime(LocalDateTime.now());
            mechanismGoodsService.add(mechanismGoods);

            // 商品规格表litemall_goods_specification
            Map<String, Integer> specIds = new HashMap<>();
            for(LitemallMechanismGoodsSpecification specification : mechanismSpecifications){
                specification.setGoodsId(mechanismGoods.getId());
                specification.setAddTime(LocalDateTime.now());
                mechanismGoodsSpecificationService.add(specification);
                specIds.put(specification.getValue(), specification.getId());
            }

            // 商品参数表litemall_goods_attribute
            for(LitemallMechanismGoodsAttribute attribute : mechanismAttributes){
                attribute.setGoodsId(mechanismGoods.getId());
                attribute.setAddTime(LocalDateTime.now());
                mechanismGoodsAttributeService.add(attribute);
            }

            // 商品货品表litemall_product
            for(LitemallMechanismProduct product : mechanismProducts){
                product.setGoodsId(mechanismGoods.getId());
                product.setAddTime(LocalDateTime.now());
                mechanismProductService.add(product);
            }
        } catch (Exception ex) {
            txManager.rollback(status);
            logger.error("系统内部错误", ex);
        }
        txManager.commit(status);
        return ResponseUtil.ok();
    }

    @GetMapping("/detail")
    public Object detail(@LoginAdmin Integer adminId, Integer id) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }

        if (id == null) {
            return ResponseUtil.badArgument();
        }

        LitemallMechanismGoods mechanismGoods = mechanismGoodsService.findEditById(id);
        List<LitemallMechanismProduct> mechanismProducts = mechanismProductService.queryByGid(id);
        List<LitemallMechanismGoodsSpecification> mechanismSpecifications = mechanismGoodsSpecificationService.queryByGid(id);
        List<LitemallMechanismGoodsAttribute> mechanismAttributes = mechanismGoodsAttributeService.queryByGid(id);

        Map<String, Object> data = new HashMap<>();
        data.put("goods" ,mechanismGoods);
        data.put("specifications", mechanismSpecifications);
        data.put("products", mechanismProducts);
        data.put("attributes", mechanismAttributes);
        return ResponseUtil.ok(data);
    }

    @GetMapping("/lookReason")
    public Object lookReason(@LoginAdmin Integer adminId, Integer id){
        if(adminId == null){
            return ResponseUtil.unlogin();
        }

        if (id == null) {
            return ResponseUtil.badArgument();
        }

        List<LitemallMechanismGoodsCheck> mechanismGoodsCheckList = mechanismGoodsCheckService.findByGoodsId(id);
        Map<String, Object> data = new HashMap<>();
        data.put("goodsCheck" ,mechanismGoodsCheckList);
        return ResponseUtil.ok(data);
    }
}